//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using CommunityServer.Components;

namespace CommunityServer.Galleries.Components
{
	/// <summary>
	/// This class contains the properties that describe a Picture.  It inherits from the base class <see cref="Post"/>.
	/// </summary>
	public class GalleryPost : Post, IThread, IComparable
	{

		#region Custom Properties

		/// <summary>
		/// This property defines the width of the image
		/// </summary>
		public int Width
		{
			get
			{
				if(this.Attachment.Width > 0)
					return this.Attachment.Width;
				
				string val = GetExtendedAttribute( "Width" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return 0;
			}
		}

		/// <summary>
		/// This property defines the height of the image
		/// </summary>
		public int Height
		{
			get
			{
				if(this.Attachment.Height > 0)
					return this.Attachment.Height;

				string val = GetExtendedAttribute( "Height" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return 0;
			}
		}


		/// <summary>
		/// This property defines the ContentType for the image, such as "image/jpeg" or "image/gif".
		/// </summary>
		[Obsolete]
		public string ContentType
		{
			get { return GetExtendedAttribute( "ContentType" ); }
			set { SetExtendedAttribute( "ContentType", value); }
		}

		[Obsolete]
		public int ImageSize
		{
			get
			{
				string val = GetExtendedAttribute( "ImageSize" );
				if(val != string.Empty)
					return int.Parse(val);
				else
					return 0;
			}
			set { SetExtendedAttribute( "ImageSize", value.ToString() ); }
		}

		public bool EnableComments
		{
			get
			{
				string val = GetExtendedAttribute( "EnableComments" );
				if(val != string.Empty)
					return bool.Parse(val);
				else
					return Galleries.GetGallery(this.SectionID).EnableComments;
			}
			set { SetExtendedAttribute( "EnableComments", value.ToString() ); }
		}

		public bool EnableExif
		{
			get
			{
				string val = GetExtendedAttribute( "EnableExif" );
				if(val != string.Empty)
					return bool.Parse(val);
				else
					return Galleries.GetGallery(this.SectionID).EnableExif;
			}
			set { SetExtendedAttribute( "EnableExif", value.ToString() ); }
		}


		#endregion

		#region CompareTo

		// *********************************************************************
		//  CompareTo
		//
		/// <summary>
		/// All forums have a SortOrder property. CompareTo compares on SortOrder
		/// to sort the forums appropriately.
		/// </summary>
		// ********************************************************************/
		public int CompareTo(object value)
		{
			if(value == null) return 1;

			return this.SortOrder.CompareTo( ((GalleryPost)value).SortOrder );
		}


		#endregion

		#region Private

        #region IThread Privates
        string mostRecentAuthor = "";   // Most recent post author
        int mostRecentAuthorID = 0;
        int mostRecentPostID = 0;       // Most recent post id
        int authorID = 0;
        #endregion
 
		private int settingsID = -1;
		private string[] categories;
		private GalleryPostType postType = GalleryPostType.Image;

		#endregion

		#region Public

		/// <summary>
		/// Used to bind the Title URL or user profile link to the CA datagrid
		/// </summary>
		public string AuthorUrl
		{
			get
			{
				if(this.HasTitleUrl)
					return this.TitleUrl;
				else
					return SiteUrls.Instance().UserProfile(this.Username); 
			}
		}
		/// <summary>
		/// Url to use instead of default title link
		/// </summary>
		public string TitleUrl
		{
			get
			{
				if(!Globals.IsNullorEmpty(this.GetExtendedAttribute("Website")))
					return this.GetExtendedAttribute("Website");
				return this.GetExtendedAttribute("TitleUrl");
			}
			set{this.SetExtendedAttribute("TitleUrl",value);}
		}

		/// <summary>
		/// Used to bind the thumbnail to the CA datagrid
		/// </summary>
		public string ThumbnailURL
		{
			get{return GalleryUrls.Instance().ThumbnailURL(this) ;}
		}
		
		/// <summary>
		/// Used to bind the Micro image to the CA datagrid
		/// </summary>
		public string MicroURL
		{
			get{return GalleryUrls.Instance().ThumbnailURL(this);}
		}

		/// <summary>
		/// Used to bind the view link to the CA datagrid
		/// </summary>
		public string ViewPictureURL
		{
			get
			{
				if(this.GalleryPostType == GalleryPostType.Image)
					return GalleryUrls.Instance().ViewPicture(this.Section.ApplicationKey, this);
				else
					return GalleryUrls.Instance().ViewPicture(this.Section.ApplicationKey, GalleryPosts.GetPicture(this.ParentID)); 
			}
		}

		/// <summary>
		/// Name of site making the trackback
		/// </summary>
		public string TrackBackName
		{
			get{return this.GetExtendedAttribute("trackbackName");}
			set{this.SetExtendedAttribute("trackbackName",value);}
		}

		/// <summary>
		/// Name submitted when the post was saved
		/// </summary>
		public string SubmittedUserName
		{
			get
			{
				if(!Globals.IsNullorEmpty(this.GetExtendedAttribute("Name")))
					return this.GetExtendedAttribute("Name");
				return GetString("SubmittedUserName",null);
			}
			set{this.SetExtendedAttribute("SubmittedUserName",value);}
		}

		/// <summary>
		/// When the post was saved, did the user submit a different name
		/// </summary>
		public bool HasSubmittedUserName
		{
			get{ return !Globals.IsNullorEmpty(this.SubmittedUserName);}
		}

		public string DisplayName
		{
			get 
			{
				if (this.GalleryPostType == GalleryPostType.Trackback)
					return TrackBackName != null ? TrackBackName : "TrackBack";

				if (this.User == null)
					this.User = Users.GetUser(this.UserID, this.Username, false, true);

				if (this.User != null && this.User.IsAnonymous && HasSubmittedUserName)
					return this.SubmittedUserName;
				else if (this.User != null)
					return this.User.DisplayName;
				else
					return this.Username;
			}
		}



        #region IThread Public Properties
        ThreadStatus status = ThreadStatus.NotSet;
        public ThreadStatus Status 
        {
            get { return status; }
            set { status = value; }
        }

        public int AuthorID 
        {
            get 
            {
                return authorID;
            }
            set 
            {
                authorID = value;
            }
        }

        // *********************************************************************
        //
        //  IsPopular
        //
        /// <summary>
        /// If thread has activity in the last 2 days and > 20 replies
        /// </summary>
        //
        // ********************************************************************/
        public bool IsPopular 
        {
            get 
            { 
                if ((ThreadDate < DateTime.Now.AddDays(GalleryConfiguration.Instance().PopularPostLevelDays)) && ( (Replies > GalleryConfiguration.Instance().PopularPostLevelPosts) || (Views > GalleryConfiguration.Instance().PopularPostLevelViews) ))
                    return true;

                return false;
            }
        }
        
        
        // *********************************************************************
        //
        //  IsAnnouncement
        //
        /// <summary>
        /// If post is locked and post date > 2 years
        /// </summary>
        //
        // ********************************************************************/
        public bool IsAnnouncement 
        {
            get 
            { 
                if ((StickyDate > DateTime.Now.AddYears(2)) && (IsLocked))
                    return true;
                else
                    return false;
            }
        }


        bool isSticky = false;
        public bool IsSticky 
        {
            get 
            {
                return isSticky;
            }
            set 
            {
                isSticky = value;
            }
        }

        DateTime stickyDate = DateTime.Now.AddYears(-25);
        public DateTime StickyDate 
        {
            get 
            {
                return stickyDate;
            }
            set 
            {
                stickyDate = value;
            }
        }


        // *********************************************************************
        //
        //  MostRecentPostAuthor
        //
        /// <summary>
        /// The author of the most recent post in the thread.
        /// </summary>
        //
        // ********************************************************************/
        public string MostRecentPostAuthor 
        {
            get 
            { 
                return mostRecentAuthor; 
            }
            set 
            { 
                mostRecentAuthor = value; 
            }
        }

        public int MostRecentPostAuthorID 
        {
            get 
            {
                return mostRecentAuthorID;
            }
            set 
            {
                mostRecentAuthorID = value;
            }
        }

        public string PreviewBody 
        {
            get 
            {
                return Transforms.StripForPreview(base.Body);
            }
        }

        // *********************************************************************
        //
        //  MostRecentPostID
        //
        /// <summary>
        /// The post id of the most recent post in the thread.
        /// </summary>
        //
        // ********************************************************************/
        public int MostRecentPostID 
        {
            get 
            { 
                return mostRecentPostID; 
            }
            set 
            { 
                mostRecentPostID = value; 
            }
        }

        #endregion

		public int SettingsID
		{
			get { return settingsID; }
			set { settingsID = value; }
		}


		public bool IsPicture
		{
			get {return (HasAttachment && Attachment.IsImage);}
		}


        public GalleryPostType GalleryPostType
        {
            get { return postType;}
			set { postType = value;}
            
        }

		/// <summary>
		/// list of categories this post was made to
		/// </summary>
		public string[] Categories
		{
			get{return categories;}
			set{categories = value;}
		}

		/// <summary>
		/// Summary of the blog feedback. Not used as an API
		/// </summary>
		public GalleryPostConfig PostConfig
		{
			get{return (GalleryPostConfig)PostConfigurationValue;}
			set{PostConfigurationValue = (int)value;}
		}
		

		public CommunityServer.Components.CommentModerationType ModerationType
		{
			get
			{
				//TODO Remove this setting from the database
				//if(GetPostConfig(GalleryPostConfig.ModerateFeedback))
				//	return CommentModerationType.All;

				return (CommentModerationType)Enum.Parse(typeof(CommentModerationType),GetString("CommentModerationType","None"),false);
			}
			set
			{
				SetExtendedAttribute("CommentModerationType",value.ToString());
			}
		}

		public bool EnableRatings
		{
			//get{return GetBool("EnableRatings",true);} <-- WeblogPost does this, here we need to inherit from the section if not set
			get{return GetBool("EnableRatings",Galleries.GetGallery(this.SectionID).EnableRatings);}
			set{ SetExtendedAttribute("EnableRatings",value.ToString());}
		}

		public bool EnableTrackBacks
		{
			get{return GetBool("EnableTrackBacks",true);}
			set{ SetExtendedAttribute("EnableTrackBacks",value.ToString());}
		}

		public bool EnableOrderPrints
		{
			get{return GetBool("EnableOrderPrints",true);}
			set{ SetExtendedAttribute("EnableOrderPrints",value.ToString());}
		}

		public bool EnableXmlRpcPings
		{
			get{return GetBool("EnableXmlRpcPings",true);}
			set{ SetExtendedAttribute("EnableXmlRpcPings",value.ToString());}
		}

		public string FormattedPostDate
		{
			get{return base.PostDate.ToString() ;}
		}

		/// <summary>
		/// Should this post syndicated the excerpt only?
		/// </summary>
		public bool SyndicateExcerpt
		{
			get{return GetPostConfig(GalleryPostConfig.SyndicateExcerpt);}
			set{SetPostConfig(GalleryPostConfig.SyndicateExcerpt, value);}
		}


		internal bool EverTracked
		{
			get{return GetBool("EverPublished",false);}
			set{ SetExtendedAttribute("EverPublished",value.ToString());}
		}

		/// <summary>
		/// returns true if the Post is approved and th PostDate is less than the current datetime
		/// </summary>
		public bool IsPostEnabled
		{
			get
			{
				return IsApproved && (this.PostDate <= DateTime.Now);
			}
		}

		//Need a better pattern here!

		/// <summary>
		/// This value is not persisted! The first time a Weblog Post is saved and EverTracked is set to true, this value
		/// will be true. CSModule subscribers can use this property to determine if one time notifications should be made.
		/// 
		/// </summary>
		internal bool EnableExternalNotificatons;

		/// <summary>
		/// The type of feedback the owner should receive notification for. Overrides the Weblog value.
		/// </summary>
		public FeedbackNotificationType FeedbackNotificationType
		{
			get{ return (FeedbackNotificationType)GetInt("feedbackNotificationType", (int)this.Gallery.FeedbackNotificationType); }
			set{ this.SetExtendedAttribute("feedbackNotificationType",((int)value).ToString()); }
		}

		public bool EnableAllOwnerNotification
		{
			get{ return GetBool("enableAllOwnerNotification", false); }
			set{ SetExtendedAttribute("enableAllOwnerNotification", value.ToString()); }

		}

		/// <summary>
		/// String version of GalleryPostType used in CA Grid data binding
		/// </summary>
		public string GalleryPostTypeName
		{
			get{return ((GalleryPostType)ApplicationPostTypeValue).ToString();}
		}


		// Photo Gallery posts always have PostMedia of Image
		public override PostMediaType PostMedia
		{
			get 
			{
				return PostMediaType.Image;
			}
		}

		#endregion

		#region Public Helpers
		
		/// <summary>
		/// Does this post have a title url
		/// </summary>
		public bool HasTitleUrl
		{
			get{return (TitleUrl != null && TitleUrl.Length > 0);}
		}

		/// <summary>
		/// Does this post of have name
		/// </summary>
		public bool HasName
		{
			get{return (Name != null && Name.Length > 0);}
		}

		/// <summary>
		/// Does this post have categories
		/// </summary>
		public bool HasCategories
		{
			get{return (Categories != null && Categories.Length > 0);}
		}

		#endregion

		#region Private Helpers

		/// <summary>
		/// Helper to set the PostConfig value
		/// </summary>
		/// <param name="gpc"></param>
		/// <param name="isSelected"></param>
		protected void SetPostConfig(GalleryPostConfig gpc, bool isSelected)
		{
			PostConfig = PostConfigHelper.SetPostConfig(PostConfig,gpc,isSelected);
		}

		/// <summary>
		/// Helper to get the current post config value
		/// </summary>
		/// <param name="gpc"></param>
		/// <returns></returns>
		protected bool GetPostConfig(GalleryPostConfig gpc)
		{
			return PostConfigHelper.IsPostConfigSelected(PostConfig,gpc);
		}



		#endregion

		#region Section
        
		private Gallery _gallery = null;
        public override Section Section
        {
            get
            {
                if(_gallery == null)
                    _gallery = Galleries.GetGallery(this.SectionID);

                return _gallery;
            }
            set
            {
                _gallery = value as Gallery;
            }
        }

		public Gallery Gallery
		{
			get{ return Section as Gallery;}
		}


        #endregion

	}
}
